#ifndef PW_PBL_COROUTINE_VECTOREXECUTOR_HPP
#define PW_PBL_COROUTINE_VECTOREXECUTOR_HPP

#include <coroutine>
#include <concepts>
#include <utility>
#include <vector>
#include "IAwaitable.hpp"

/// 协程名字空间
/// @note 本库的协程使用类似Javascript的单线程模型，多线程使用时各线程均可开启自己的协程执行器，
/// 但各线程的协程之间通信时需要另加同步机制，尤其注意co_await另一个线程的协程或等待器并不安全
namespace pw_pbl::co
{
	/// 协程向量执行器类
	struct VectorExecutor
	{
		struct IAwaitable;

		struct ExecItem
		{
			IAwaitable *awaitor;
			constexpr ExecItem(IAwaitable &aw) : awaitor(&aw) {}
			constexpr bool operator==(const ExecItem &oth) const = default;
		};

		struct IAwaitable : public co::IAwaitable<IAwaitable>
		{
			~IAwaitable(void) noexcept;
		};

		std::vector<ExecItem> queue;
		std::vector<ExecItem> pending;

		void await_suspend(IAwaitable &fr);

		/// 运行协程队列
		/// @return 队列是否已空
		bool run(void) &;

		inline auto next(void)
		{
			return [pre = 0]() mutable { return pre++; };
		}

		VectorExecutor() = default;

	private:
		VectorExecutor(const VectorExecutor &) = delete;
		VectorExecutor(VectorExecutor &&) = delete;
		VectorExecutor &operator=(const VectorExecutor &) = delete;
		VectorExecutor &operator=(VectorExecutor &&) = delete;
	};
} // namespace pw_pbl::co

#endif // PW_PBL_COROUTINE_VECTOREXECUTOR_HPP
